﻿using System;
using System.Collections.Generic;
using System.Text;

using Kitware.VTK;

namespace Fu3DEngine
{
   public  class TerrainInfo
   {

       #region "属性封装"

 

       //这个东西要不要呢，他可是不能序列化的
       public vtkImageData imgData;
       public vtkImageData ImgData
       {
           get { return imgData; }
       }
     public void SetImageData(vtkImageData img)
     {
         imgData = img;
         this.scalarRange = imgData.GetScalarRange();
         this.spatialR = imgData.GetSpacing();
         this.orgPoint = imgData.GetOrigin();
         this.dimension = imgData.GetDimensions();


         centerPt = new double[3];
         centerPt[0] = this.orgPoint[0] + this.spatialR[0] * this.dimension[0] / 2;
         centerPt[1] = this.orgPoint[1] + this.spatialR[1] * this.dimension[1] / 2;
         centerPt[2] = (this.scalarRange[1] - this.scalarRange[0]) * this.spatialR[2] / 2;

         bImageSeted = true;

     }

     double[] centerPt;
     public double[] CenterPoint
     {
         get { return centerPt; }
     }


       double[] spatialR;//每个格子边长的实际意义

       public double[] SpatialR
       {
           get { return spatialR; }
          
       }

       double[] scalarRange;
       /// <summary>
       /// 0min,1max
       /// </summary>
       public double[] ScalarRange
       {
           get { return scalarRange; }
       }


       double[] orgPoint;
       public double[] OrgPoint
       {
           get { return orgPoint; }
       }



       int[] dimension;
       /// <summary>
       /// rows是0，cols是1
       /// </summary>
       public int[] Dimension
       {

           get { return dimension; }
       }

       //根据行列取得对应的值
       public double GetScalarFromImage(int x,int y)
       {
           double mz = imgData.GetScalarComponentAsDouble(x, y, 0, 0);
           return mz;
 
       }

       public double GetBaseHeight(double x, double y)

       {

           if (!bImageSeted)
           {
               return 0;
           }


           double mx = (x - orgPoint[0]) / spatialR[0];
           double my = (y - orgPoint[1]) / spatialR[1];


           //通过优化的加权方式计算点高度
           int ceilx =(int) Math.Ceiling(mx);
           int floorx = (int)Math.Floor((mx));
           int ceily = (int)Math.Ceiling(my);
           int floory = (int)Math.Floor(my);

           double weightx = mx - floorx;
           double weighty = my - floory;




           //以所有值的最小点为一,左下点为一号，顺时针旋转
           double m1 = imgData.GetScalarComponentAsDouble(floorx, floory,0,0);
           double m2 = imgData.GetScalarComponentAsDouble(floorx, ceily,0,0);
           double m3 = imgData.GetScalarComponentAsDouble(ceilx, ceily,0,0);
           double m4 = imgData.GetScalarComponentAsDouble(ceilx, floory,0,0);


           double mz = m1 * (1 - weightx) * (1 - weightx) + m2 * (1 - weightx) * (weighty) + m3 * (weightx) * (weighty) + m4 * (weightx) * (1 - weighty);


         //double mz= imgData.GetScalarComponentAsDouble((int)mx,(int)my,0,0);

         return mz;


       }


       /// <summary>
       /// 这里只是暂时使用的，还未充分考虑多种兼容问题
       /// </summary>
       /// <param name="meter"></param>
       /// <returns></returns>
       public double GetHeightFromMeter(double meter)
       {
           if (!bImageSeted)
           {
               return meter;
           }


           return meter /spatialR[2];

       }

       public int[] PointToGridPoint(double x,double y)
       {
           int[] xy=new int[2];
           double mx = (x - orgPoint[0]) / spatialR[0];
           double my = (y - orgPoint[1]) / spatialR[1];

           xy[0] = (int)mx; 
           xy[1] = (int)my;

           return xy;
 
       }

       public double[] GetTerrainPoint(double x, double y)
       {
           double z = this.GetBaseHeight(x, y);
           double[] pt = new Double[3];
           pt[0] = x;
           pt[1] = y;
           pt[2] = z;

           return pt;
       }


      
       //是否是无地形图像信息
       bool bImageSeted = false;


       //是否启用纹理，并投射
       bool bShowTexture{get;set;}
       


       #endregion





   }
}
